using System;
using System.Runtime.Serialization;
using OhioState.AssetManaged;
using OhioState.Math;

namespace OhioState.Graphics.Proxy
{
    [Serializable]
    public class ROIBoxProxy : SharedAsset, IDrawable
    {
        private float _sliceThickness = 0.005f;
        public float SliceThickness
        {
            get { return _sliceThickness; }
            set
            {
                _sliceThickness = value;
                FireUpdateChangedEvent(this);
            }
        }
        private SliceDirection.SliceDirMode _sliceMode;
        public SliceDirection.SliceDirMode SlicingMode
        {
            get { return _sliceMode; }
            set
            {
                _sliceMode = value;
                FireUpdateChangedEvent(this);
            }
        }
        private Vector3 _sliceDirection = new Vector3(1.0f,0.0f,1.0f);
        public Vector3 SliceDirection
        {
            get { return _sliceDirection; }
            set
            {
                _sliceDirection = value;
                FireUpdateChangedEvent(this);
            }
        }

        
        private Matrix4 _worldToROI = new Matrix4();
        public Matrix4 WorlToROIMatrix
        {
            get { return _worldToROI; }
            set
            {
                _worldToROI = value;
                FireUpdateChangedEvent(this);
            }

        }
        private Matrix4 _roiToTexture = new Matrix4();
        public Matrix4 ROIToTextureMatrix
        {
            get { return _roiToTexture; }
            set
            {
                _roiToTexture = value;
                FireUpdateChangedEvent(this);
            }
        }
        private SharedBox _box;
        public SharedBox Box
        {
            get { return _box; }
            set 
            {
                IAssetManagedHandler changedEvent = new IAssetManagedHandler(Box_ChangedEvent);
                this.SetPropertyEventHandling(_box, value, changedEvent);
                _box = value;
                Box_ChangedEvent(_box);
            }
        }

        //private ClipPlaneProxy clip1, clip2, clip3;
        //public ClipPlaneProxy Clip1
        //{
        //    get { return clip1; }
        //    set
        //    {
        //        clip1 = value;
        //        FireUpdateChangedEvent(this);
        //    }
        //}
        //public ClipPlaneProxy Clip2
        //{
        //    get { return clip2; }
        //    set
        //    {
        //        clip2 = value;
        //        FireUpdateChangedEvent(this);
        //    }
        //}
        //public ClipPlaneProxy Clip3
        //{
        //    get { return clip3; }
        //    set
        //    {
        //        clip3 = value;
        //        FireUpdateChangedEvent(this);
        //    }
        //}
        //public void ChangeClip(ClipPlaneProxy clip, int index)
        //{
        //    if (true)
        //    {
        //        switch (index)
        //        {
        //            case 1: Clip1 = clip;
        //                break;
        //            case 2: Clip2 = clip;
        //                break;
        //            case 3: Clip3 = clip;
        //                break;
        //            default: break;
        //        }
        //        //FireUpdateChangedEvent(this);
        //    }
        //}
       
        private ClipPlaneProxy noclip;
        #region IDrawable interface
        public IBoundingVolume BoundingVolume
        {
            get { return _box.BBox; }
        }
        public void Update(IRenderPanel panel)
        {
        }
        private MaterialProxy _material;
        public IMaterial Material
        {
            get { return _material; }
            set
            {
                //
                // For fields that contain shared objects, follow this sequence:
                //   1. rewire the notification for the shared object
                //        this property points to.
                //   2. set the property.
                //   3. perform any internal updates.
                //   4. Implicit in step 3 would be changing this 
                //         object and hence notifying it's subscribers.
                //
                IAssetManagedHandler changedEvent = new IAssetManagedHandler(Box_ChangedEvent);
                MaterialProxy mat = value as MaterialProxy;
                if (mat != null)
                {
                    this.SetPropertyEventHandling(_material, mat, changedEvent);
                    _material = mat;
                    Box_ChangedEvent(mat);
                }
            }
        }
        public void Render(IRenderPanel panel)
        {
        }
        #endregion IDrawable interface

       
        public ROIBoxProxy(String name, SharedBox box)
            : base(name)
        {
            _material = MaterialProxy.White;
            IAssetManagedHandler changedEvent = new IAssetManagedHandler(Box_ChangedEvent);
            _box = box;
            _box.AddChangedEventHandler(changedEvent);
            noclip = new ClipPlaneProxy("NoClip");
            //Clip1 = new ClipPlaneProxy("NoClip");
            //Clip2 = new ClipPlaneProxy("NoClip");
            //Clip3 = new ClipPlaneProxy("NoClip");
            //Clip1 = Clip2 = Clip3 = noclip;

        }
        public ROIBoxProxy(SharedBox box)
            : this("", box)
        {
           
            noclip = new ClipPlaneProxy("NoClip");
            //Clip1 = new ClipPlaneProxy("NoClip");
            //Clip2 = new ClipPlaneProxy("NoClip");
            //Clip3 = new ClipPlaneProxy("NoClip");
            //Clip1 = Clip2 = Clip3 = noclip;

        }
        private void Box_ChangedEvent( IAssetManaged obj )
        {
            FireUpdateChangedEvent(this);
        }
        /// <summary>
        /// Overrides shared object ToString method
        /// </summary>
        /// <returns>A string representing parent shared object name</returns>
        public override String ToString()
        {
            return base.Name;
        }
        public override void ReaquireAssets()
        {
            //
            // Use the Properties to ensure the old event handlers are removed and new
            //    ones are added. Particularly if we are setting an item to itself.
            //
            IAssetManaged item = AssetManager.Instance.Find(_box.GetType(), _box.Name);
            if (item != _box)
            {
                this.Box = item as SharedBox;
            }
            item = AssetManager.Instance.Find(_material.GetType(), _material.Name);
            if (item != _box)
            {
                this.Material = item as IMaterial;
            }
        }
        [OnDeserialized]
        private void OnDeserialized(StreamingContext context)
        {
            IAssetManagedHandler changedEvent = new IAssetManagedHandler(Box_ChangedEvent);
            _box.AddChangedEventHandler(changedEvent);
            _material.AddChangedEventHandler(changedEvent);
        }
    }
}
